Introduction

Addressing modes refer to the supported methods for accessing and manipulating data. There are three basic addressing modes in x86-64: register, immediate and memory.

Register Mode Addressing

In register mode addressing, the operand is a register (brain undergoing nuclear-fission).

mov rax, rbx

The value inside rbx is copied to rax.

Immediate Mode Addressing

In immediate mode addressing, the operand is an immediate value, or a literal. These are simply constant values such as 10, 0xfa3, "lol", and so on.

mov rax, 123

The number 123 is copied into rax.

Memory Mode Addressing

In memory mode addressing, the operand is treated as a memory location. This is referred to as indirection or dereferencing and is similar to how pointers can be dereferenced in C/C++. In assembly, this is done by wrapping the operand in square brackets: [].

So for example, rax refers to the value stored within the register rax. However, [rax] means "treat rax like a pointer and use the value it points to". Essentially, [rax] treats the value inside the register as an address and uses that address to find the actual value it needs.

mov DWORD PTR [rax], 0xdeadbeef

The value 0xdeadbeef is copied into the location pointed to by rax.

Since memory is byte-addressable, it is oftentimes required to specify how many bytes we want to access. This is done by prepending one of the following specifiers to the operand:

SpecifierNumber of Bytes
BYTE PTR / byte1
WORD PTR / word2
DWORD PTR / dword4
QWORD PTR / qword8

Moreover, the actual formula for memory addressing is a bit more complicated, since it was developed mainly for making the implementation of arrays easier.

[baseAddr + (indexReg * scaleValue) + offset]

The baseAddr must be a register or variable name, although it may be omitted in which case the address is relative to the beginning of the data segment. indexReg is a register which specifies contains an index into the array and the scaleValue is the size (in bytes) of a single member of the array. The offset must be an immediate value.

mov eax, dword [ebx] ; move into eax the value which ebx points to
mov rax, QWORD PTR [rbx + rsi] ; move into rax the value which (rbx + rsi) points to
mov rcx, qword [rax+(rsi*8)] ; move into rcx the value which (rax + (rsi*8)) points to